"""
@version: v1.0
@author: wangwenjie
@Email: wwjessie1997@outlook.com
@software: PyCharm
@project: Tool-Code
@file: Drawing Chart.py
@time: 2025/1/24 17:22
@desc: 画图表
"""

import os
import datetime
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.colors as colors
import matplotlib.pyplot as plt
from copy import deepcopy
from collections import OrderedDict
from matplotlib.pyplot import MultipleLocator
#from pyecharts import options as opts

plt.style.use('ggplot')
mpl.rcParams['font.sans-serif'] = [u'SimHei']  # 指定默认字体
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
mpl.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
mpl.rcParams['legend.frameon'] = 'False'

# 画净值图
def fig_nav(fn, Port, title, ncol, path):
    fig = plt.figure(figsize=(30, 15))
    ax1 = fig.add_subplot(111)
    ax1.set_title('{}'.format(fn), fontsize=40)
    # 绘制plot图
    for c in Port.columns:
        ax1.plot(Port[c], linewidth=5, label=c)
    # 设置X,Y轴字体大小和颜色
    for ticks in plt.gca().xaxis.get_major_ticks():
        ticks.label1.set_fontsize(20)
        ticks.label1.set_color('black')
    for ticks in plt.gca().yaxis.get_major_ticks():
        ticks.label1.set_fontsize(20)
        ticks.label1.set_color('black')
    # 设置横轴最大间隔
    x_major_locator = MultipleLocator(200)
    ax1.xaxis.set_major_locator(x_major_locator)
    # 设置画布和图例
    plt.gca().set_facecolor('white')
    handles, labels = plt.gca().get_legend_handles_labels()
    by_label = OrderedDict(zip(labels, handles))
    plt.legend(by_label.values(), by_label.keys(), loc='center left', bbox_to_anchor=(1,0.5), ncol=ncol, fontsize=25)
    plt.savefig(os.path.join(path, '{}.png'.format(fn)), bbox_inches='tight')
    return

# 画柱状图
def fig_bar(Port, title, path):
    fig = plt.figure(figsize=(12,6))
    ax = fig.add_subplot(1,1,1)
    Port.plot.bar(ax=ax)
    for tick in ax.get_xticklabels():
        tick.set_rotation(0)
    ax.legend(loc = 'best')
    ax.set_title('{}'.format(title), fontsize = 25)
    plt.savefig(os.path.join(path, '{}.png'.format(title)), bbox_inches='tight')
    return

# 画簇状柱状图
def fig_bar(Port, title, path):
    fig = plt.figure(figsize=(12,6))
    ax = fig.add_subplot(1,1,1)
    Port.plot.bar(ax=ax)
    # 设置坐标轴旋转
    for tick in ax.get_xticklabels():
        tick.set_rotation(0)
    ax.legend(loc=3)
    ax.set_title('%s' % (title))
    plt.savefig(os.path.join(path, '{}.png'.format(title)), bbox_inches='tight')
    return

# 画累计柱状图
def fig_bar(Port, title, path):
    fig = plt.figure(figsize=(12,6))
    # 设置横轴
    x = np.array(Port.index)
    # name1-name4,为Port Columns，即图例
    y1 = np.array(Port[name1].tolist())
    y2 = np.array(Port[name2].tolist())
    y3 = np.array(Port[name3].tolist())
    y4 = np.array(Port[name4].tolist())
    ax1.bar(x, y1, label='%s' % (name1), color='lightsalmon')
    ax1.bar(x, y2, bottom=y1, label='%s' % (name2), color='darkseagreen')
    ax1.bar(x, y3, bottom=y1 + y2, label='%s' % (name3), color='grey')
    ax1.bar(x, y4, bottom=y1 + y2 + y3, label='%s' % (name4), color='skyblue')
    plt.savefig(os.path.join(path, '{}.png'.format(title)), bbox_inches='tight')
    return

# 画散点图
def fig_bar_stack(Port,name1,name2):
    fig = plt.figure()
    fig = plt.figure(figsize=(12,6))
    ax = fig.add_subplot(1,1,1)
    ax.scatter(Port[name2],Port[name1], label='%s VS %s' % (name1, name2))
    ax.scatter(Port[name2][-1],Port[name1][-1],c='r', label='当前%s VS %s' % (name1, name2))
    ax.scatter(Port[name2][-2],Port[name1][-2],c='y', label='上周%s VS %s' % (name1, name2))
    plt.gca().set_facecolor('white')
    ax.legend(loc=1)
    ax.set_xlabel(name1)
    ax.set_ylabel(name2)
    return

# 画雷达图
def fig_radar(port, title, l1, l2, Δ):    
    # 准备数据
    categories = port.index
    N = len(categories)
    color = ["red", "blue", "green", "yellow", "purple", "orange", "pink", "black", "white", "gray"]
    # 计算角度并闭合数据
    angles = np.linspace(0, 2 * np.pi, N, endpoint=False).tolist()
    angles += angles[:1]
    # 创建画布&绘制多组数据
    fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))
    for i in range(len(port.columns)):
        values = port.iloc[:,i].tolist()
        values += values[:1]
        ax.plot(angles, values, '-', linewidth=2, color=color[i], label=port.columns[i])
        #ax.fill(angles, values, alpha=0.2, color='#1f77b4')
    # 设置刻度和标签
    ax.set_xticks(angles[:-1])
    ax.set_xticklabels(categories, fontsize=12)
    ax.set_ylim(l1, l2)
    ax.set_yticks(np.arange(l1, l2, Δ))
    ax.set_yticklabels([f'{x:.1f}' for x in np.arange(l1, l2, Δ)], fontsize=10)
    # 美化设置
    ax.grid(True, linestyle='--', alpha=0.7)  # 网格线
    ax.set_title('{}-{}'.format(a, title), fontsize=16, pad=30)
    ax.legend(loc='upper right', bbox_to_anchor=(1.3, 1.0), fontsize=10)
    # 图片展示&保存
    plt.tight_layout()
    save_dir = os.path.join(new_dir, '{}-雷达图'.format(title))
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)
    plt.savefig(os.path.join(save_dir, '{}-{}.png'.format(a, title)), bbox_inches='tight')
    plt.show()
    return

# 折线图叠加面积图(右轴)
def fig_plot_area(Port,name1,name2):
    fig = plt.figure(figsize=(12,6))
    # 绘制折线图
    plt.ylim(l1, l2) # 设置左轴的范围
    ax1.plot(np.array(Port[name1].tolist()), lw=1.5, label='%s' % (name1))
    ax1.plot(np.array(Port[name2].tolist()), lw=1.5, label='%s' % (name2))
    ax1.plot(np.array(Port[name3].tolist()), lw=1.5, label='%s' % (name3))
    # 设置右坐标轴
    ax2 = ax1.twinx()
    # 绘制面积图
    plt.ylim(l3, l4) # 设置右轴的范围
    Port[name4].plot.area(stacked=False, ax=ax2, label='%s' % (name4), color='gray', linewidth=0)
    ax1.legend(ncol=3, loc=2)
    ax2.legend(loc=1)
    ax2.grid(False) # 取消网格
    return

# 同画布多图拼接
def fig_complex(list, df_all): # list子图名称; df_all为输入的数据表，可以提取dfi;
    # 处理数据
    df_list = []
    for i in range(len(list)):
        df_list.append(dfi) # dfi为子图数据表
    # 画图代码
    fig = plt.figure(figsize=(60, 50)) #画布大小
    plt.subplots_adjust(left=None,bottom=None,right=None,top=None,wspace=0.5,hspace=0.15) #设置子图之间的位置关系
    plt.gca().set_facecolor('white')
    for i in range(len(list)):
        ax = fig.add_subplot(2, 4, i + 1)
        # 后面为画图的主体代码
    return

